import { app, BrowserWindow, ipcMain } from 'electron'
import path from 'node:path'
import { spawn, exec } from 'child_process'
import http from 'http'


// The built directory structure
//
// ├─┬─┬ dist
// │ │ └── index.html
// │ │
// │ ├─┬ dist-electron
// │ │ ├── main.js
// │ │ └── preload.js
// │
process.env.DIST = path.join(__dirname, '../dist')
process.env.VITE_PUBLIC = app.isPackaged ? process.env.DIST : path.join(process.env.DIST, '../public')


let win: BrowserWindow | null
// 🚧 Use ['ENV_NAME'] avoid vite:define plugin - Vite@2.x
const VITE_DEV_SERVER_URL = process.env['VITE_DEV_SERVER_URL']

function createWindow() {
  win = new BrowserWindow({
    frame: true,
    autoHideMenuBar: true,
    icon: path.join(process.env.VITE_PUBLIC, 'electron-vite.svg'),
    height: 800,
    width: 1600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: true,
      contextIsolation: false,
    },
  })

  // 创建HTTP服务器
  const server = http.createServer((req, res) => {
    // 处理接收到的数据
    let data = ''; 

    req.on('data', chunk => {
      data += chunk;
    });
    req.on('end', () => {
      // 将数据发送到渲染进程
      console.log('Received data from C++:', data);
      win?.webContents.send('http-data', data);
      res.end('Data received');
    });
  });

  server.listen(9999); // 监听端口

  // Test active push message to Renderer-process.
  win.webContents.on('did-finish-load', () => {
    win?.webContents.send('main-process-message', (new Date).toLocaleString())
  })

  if (VITE_DEV_SERVER_URL) {
    win.loadURL(VITE_DEV_SERVER_URL)
  } else {
    // win.loadFile('dist/index.html')
    win.loadFile(path.join(process.env.DIST, 'index.html'))
  }
}

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
    win = null
  }
})

app.on('activate', () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})

app.whenReady().then(createWindow)

// 监听从渲染进程发送的消息
ipcMain.on('execute-executable', (event, args) => {
  const { executablePath, parameters } = args;

  // console.log('path:', executablePath, parameters);
  // 执行可执行文件
  const childProcess = spawn(executablePath, parameters);

  // 处理可执行文件的输出
  childProcess.stdout.on('data', (data) => {
    console.log(`stdout: ${data}`);
  });

  childProcess.stderr.on('data', (data) => {
    console.error(`stderr: ${data}`);
  });

  childProcess.on('close', (code) => {
    //向渲染进程发送消息
    event.sender.send('process-exit', `child process exited with code ${code}`);
    console.log(`child process exited with code ${code}`);
  });
});


// 监听从渲染进程发送的消息，执行关闭指定进程操作
//@ts-ignore
ipcMain.on('kill-process', (event, args) => {
  const { processID } = args;
  exec(`taskkill /f /pid ${processID}`, (error, stdout, stderr) => {
    if (error) {
      console.error(`执行出错: ${error}`);
      return;
    }
    console.log(`stdout: ${stdout}`);
    console.error(`stderr: ${stderr}`);
  });
});